package com.gblfy.httpclinet.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * 使用httpclint 发送/上传文件
 *
 * @author gblfy
 * @date 2021-10-12
 */
public class UpLoadFileUtil {

    private static Logger logger = LoggerFactory.getLogger(UpLoadFileUtil.class);

    @Autowired
    private HttpServletRequest paramRequest;
    /**
     * 通过httpClient上传文件
     *
     * @param fileName 文件名称
     * @param path     本地文件路径
     * @param url      远程上传接口url
     * @return
     */
    public static String UploadFileByHttpClient(String fileName, String path, String url) {
        String result = "";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        InputStream content = null;
        BufferedReader in = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            //HttpMultipartMode.RFC6532参数的设定是为避免文件名为中文时乱码
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            //httpPost.addHeader来自定义header参数 ,头部放文件上传的head可自定义
            httpPost.addHeader("header1", "111");
            File file = new File(path + fileName); //上传文件的路径
            builder.addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, fileName);

            //builder.addTextBody来自定义其他参数，相当于html中form表单中其他的<input>参数，可解析返回来的result拿到自己想拿的信息
            builder.addTextBody("params1", "1");//其余参数，可自定义
            builder.addTextBody("params2", "2");
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);// 执行提交
            HttpEntity responseEntity = response.getEntity();//接收调用外部接口返回的内容
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回的内容都在content中
                content = responseEntity.getContent();
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
                if (!StringUtils.isBlank(result)) {
                    logger.info("上传文件" + fileName + "返回参数==>" + result);
                } else {
                    logger.error("上传文件失败：返回result为null");
                }

            }
        } catch (Exception e) {
            logger.error("上传文件失败：", e);
        } finally {//处理结束后关闭httpclient的链接
            try {
                httpClient.close();
                content.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 上传MultipartFile类型的文件
     *
     * @param remoteUploadUrl 远程上传的url
     * @param file            上传的文件
     * @param fileParamName   文件参数（非文件名）
     * @param headerParams    头部信息（约定或者自定义）
     * @param otherParams     其他信息
     * @return
     */
    public static String uploadFile(String remoteUploadUrl, MultipartFile file, String fileParamName, Map<String, String> headerParams, Map<String, String> otherParams) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            String fileName = file.getOriginalFilename();
            HttpPost httpPost = new HttpPost(remoteUploadUrl);

            if (headerParams != null) {
                //添加header
                for (Map.Entry<String, String> e : headerParams.entrySet()) {
                    httpPost.addHeader(e.getKey(), e.getValue());
                }
            }

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(Charset.forName("utf-8"));
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//加上此行代码解决返回中文乱码问题
            builder.addBinaryBody(fileParamName, file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            for (Map.Entry<String, String> e : otherParams.entrySet()) {
                builder.addTextBody(e.getKey(), e.getValue());// 类似浏览器表单提交，对应input的name和value
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 上传File类型的文件
     *
     * @param file          上传的文件
     * @param fileParamName 表单名称
     * @return 响应结果
     */
    public static String uploadFile(String url, File file, String fileParamName, Map<String, String> headerParams, Map<String, String> otherParams) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            String fileName = file.getName();

            HttpPost httpPost = new HttpPost(url);
//            HttpPost httpPost = new HttpPost(url+"?token="+token+"&mobile="+mobile+"&policyNo="+policyNo);
            if (headerParams != null) {
                //添加header
                for (Map.Entry<String, String> e : headerParams.entrySet()) {
                    httpPost.addHeader(e.getKey(), e.getValue());
                }
            }
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(Charset.forName("utf-8"));
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//加上此行代码解决返回中文乱码问题
            builder.addBinaryBody(fileParamName, fileInputStream, ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            if (otherParams != null) {
                for (Map.Entry<String, String> e : otherParams.entrySet()) {
                    builder.addTextBody(e.getKey(), e.getValue());// 类似浏览器表单提交，对应input的name和value
                }
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交

            System.out.println(response.getStatusLine().getStatusCode());
            if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
                HttpEntity responseEntity = response.getEntity();
                if (responseEntity != null) {
                    // 将响应内容转换为字符串
                    result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @Test
    public void testUploadFileTypeFile() {
        //-----------------------------------------测试上传File类型的文件------------------------------------------------------
        //远程上传的url
        String remoteUploadUrl = "http://192.168.xxx.xxx:8080/项目名/provide/uploadPoliciesMti";
        //第三方提供的鉴权token
        String token = "123456";

        //模拟上上传的文件的绝对路径
        String patha = "D:\\20190905140907795.png";
        //模拟上上传的文件
        File file = new File(patha);
        //开始上传文件
        String result = uploadFile(remoteUploadUrl + "?token=" + token, file, "file", null, null);
        System.out.println(result);
    }


    @Test
    public void testUploadMultipartFileTypeFile() {
//         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
//         List<MultipartFile> files = multipartRequest.getFiles("repayFile");//从request中获取前端穿过来的文件
//         //远程上传的url
//         String remoteUploadUrl = "http://192.168.xxx.xxx:8080/项目名/provide/uploadPoliciesMti";
// //调用httpclient
//         String res = uploadFile(remoteUploadUrl, files.get(0), "repayFile", headers, paramMap);
    }

    // public static void main(String[] args) throws FileNotFoundException {
    //
    //
    // }
}
